/**
 * @file shmem.h
 * Betriebssysteme Shared Memory File Header.
 *
 * Beispiel 2
 *
 * @author Markus Scharitzer 1410258040 <markus.scharitzer@technikum-wien.at>
 * @author Helene Wiesinger 1410258004 <helene.wiesinger@technikum-wien.at>
 * @author Siegfried Becher 141025035 <siegfried.becher@technikum-wien.at>
 * @date 2015/06/04
 *
 * @version 1.0
 *
 *
 */
#ifndef SHMEM_H
#define SHMEM_H 1
/* includes */

#include <unistd.h>
#include <sem182.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>
#include <limits.h>
/* defines */
#define SEMKEY_W (1784009)
#define SEMKEY_R (1784010)
#define SHMEMKEY (1784011)

#define SUCCESS 0
#define ERROR -1
#define TRUE 1
#define FALSE 0

/* functions */
/**
 *
 * \brief get shared memory
 *
 * Creates or returns a shared memory of given size with given key
 *
 * \param memkey key for shared memory
 * \param size size of shared memory
 *
 * \return id to access the shared memory
 *
 */

int get_shmem(key_t memkey, size_t size);

/**
 *
 * \brief creates semaphores
 *
 * Returns and in case that there is no sempahre for given key creates it.
 *
 * \param semkey key of the semaphore
 * \param initval initial value of the semaphore
 *
 * \return semaphore id for using it
 *
 */
int get_semid(key_t semkey, int initval);

/**
 *
 * \brief attach a shared memory to a process
 *
 * attaches a shared memory to a process, so that it can access it.
 * also sets the internal locks, so we know, which process still
 * has an attached memory.
 *
 * \param shmid id of memory to attach
 * \param pnShm pointer to start of memory
 * \param process id of process
 *
 */
void attach_shmem(int shmid, int **pnShm, int process);

/**
 *
 * \brief detach a shared memory from a process
 *
 * detaches a shared memory from process, so that it can be deleted.
 * also removes the internal locks, so we know, which process still
 * has an attached memory.
 *
 * \param key for shared memory
 * \param process id of process
 *
 */
int detach_shmem(int key,int process);

/**
 *
 * \brief checks the params
 *
 * checks if params are valid, in the form of: -m <ringbuffer elements>
 * and if there are more params than specified
 * also checks if <ringbuffer elements> is a valid number and in the range of INT_MAX
 * \param argc from main()
 * \param *argv[] from main()
 * \return returns the size for the ringbuffer or -1 if ERROR
 *
 */
int check_arguments(int argc, char *argv[]);

/**
 *
 * \brief prints the usage
 *
 */
void print_usage(void);

/**
 *
 * \brief removes all resources
 *
 * tries to remove semaphore, detach shared memory, and if last
 * process clears its lock, tries to remove the shared memory.
 * will try to remove everything. if nothing bad happens, it
 * will run to the end.
 *
 * \param semid id of semaphore to release
 * \param shmaddr start address of the shared memory
 * \param shmid shared memory id
 * \param process key of process
 *
 */
int clean_up(int semid, int **shmaddr, int shmid, int process);

#endif
